package com.freecloud.spring.formework.webmvc.servlet;

import com.freecloud.spring.formework.annotation.FCRequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: maomao
 * @Date: 2019-12-16 08:37
 */
public class FCHandlerAdapter {

    public boolean supports(Object handler){
        return handler instanceof FCHandlerMapping;
    }

    public FCModleAndView handler(HttpServletRequest request, HttpServletResponse resopnse,Object handler) throws InvocationTargetException, IllegalAccessException {

        FCHandlerMapping handlerMapping = (FCHandlerMapping) handler;

        //把方法的形参列表与request的参数列表进行对应
        Map<String,Integer> paramIndexMapping = new HashMap<>();

        Method method = handlerMapping.getMethod();

        //提取方法中加了注解的参数
        //把方法上的注解拿到，得到的是一个二维数组
        //因一个参数可能有多个注解，而一个方法又有多个参数
        Annotation[] [] pa = method.getParameterAnnotations();

        for (int i = 0;i < pa.length;i++){

            for (Annotation a : pa[i]){
                if(a instanceof FCRequestParam){
                    String paramName = ((FCRequestParam) a).value();
                    if(!"".equals(paramName.trim())){
                        paramIndexMapping.put(paramName,i);
                    }
                }
            }
        }
        //提取方法中的request和response
        Class<?>[] paramsTypes = method.getParameterTypes();
        for (int i = 0; i < paramsTypes.length; i++) {
            Class<?> type = paramsTypes[i];
            if(type == HttpServletRequest.class || type == HttpServletResponse.class){
                paramIndexMapping.put(type.getName(),i);
            }
        }

        //赋值

        Map<String,String[]> params = request.getParameterMap();

        //实参列表
        Object[] paramValues = new Object[paramsTypes.length];


        for (Map.Entry<String, String[]> parm : params.entrySet()) {
            String value = Arrays.toString(parm.getValue()).replaceAll("\\[|\\]","")
                    .replaceAll("\\s",",");
            if(!paramIndexMapping.containsKey(parm.getKey())){
                continue;
            }
            int index = paramIndexMapping.get(parm.getKey());
            paramValues[index] = caseStringValue(value,paramsTypes[index]);
        }

        if(paramIndexMapping.containsKey(HttpServletRequest.class.getName())){
            int reqIndex = paramIndexMapping.get(HttpServletRequest.class.getName());
            paramValues[reqIndex] = request;
        }

        if(paramIndexMapping.containsKey(HttpServletResponse.class.getName())){
            int reqIndex = paramIndexMapping.get(HttpServletResponse.class.getName());
            paramValues[reqIndex] = request;
        }

        Object returnValue = method.invoke(((FCHandlerMapping) handler).getController(),paramValues);
        if(returnValue == null || returnValue instanceof Void){
            return null;
        }

        boolean isModelAndView = method.getReturnType() == FCModleAndView.class;
        if(isModelAndView){
            return (FCModleAndView) returnValue;
        }
        return null;
    }

    private Object caseStringValue(String value, Class<?> paramsType) {
        if(String.class == paramsType){
            return value;
        }
        //可使用策略模式对各种类型进行处理
        if(Integer.class == paramsType){
            return Integer.valueOf(value);
        }else if(Double.class == paramsType){
            return Double.valueOf(value);
        }else{
            //对象类型
            return value;
        }
    }
}
